// 07_common_collections.rs
// Rust 常见集合教程

fn main() {
    // 1. Vector（动态数组）
    // 创建空的 vector
    let v: Vec<i32> = Vec::new();
    
    // 使用宏创建包含初始值的 vector
    let v = vec![1, 2, 3];
    
    // 更新 vector
    let mut v = Vec::new();
    v.push(5);
    v.push(6);
    v.push(7);
    v.push(8);
    
    // 读取 vector 元素
    let third: &i32 = &v[2];
    println!("第三个元素是: {}", third);
    
    match v.get(2) {
        Some(third) => println!("第三个元素是: {}", third),
        None => println!("没有第三个元素"),
    }
    
    // 遍历 vector 中的元素
    let v = vec![100, 32, 57];
    for i in &v {
        println!("元素: {}", i);
    }
    
    // 遍历可变 vector 引用并修改元素
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50;
    }
    
    for i in &v {
        println!("修改后的元素: {}", i);
    }
    
    // 使用迭代器和 map 来修改元素（函数式编程风格）
    let v = vec![100, 32, 57];
    let updated_v: Vec<i32> = v.into_iter()
        .map(|x| x + 50)
        .collect();
    
    for i in &updated_v {
        println!("使用 map 修改后的元素: {}", i);
    }
    
    // 2. 使用枚举存储不同类型的值
    #[derive(Debug)]
    enum SpreadsheetCell {
        Int(i32),
        Float(f64),
        Text(String),
    }
    
    let row = vec![
        SpreadsheetCell::Int(3),
        SpreadsheetCell::Text(String::from("blue")),
        SpreadsheetCell::Float(10.12),
    ];
    
    for cell in &row {
        println!("单元格值: {:?}", cell);
    }
    
    // 3. String（字符串）
    // 创建新的空字符串
    let mut s = String::new();
    
    // 使用 to_string() 方法
    let data = "initial contents";
    let s = data.to_string();
    
    // 直接使用字符串字面量
    let s = "initial contents".to_string();
    
    // 使用 String::from() 函数
    let s = String::from("initial contents");
    
    // 更新字符串
    let mut s = String::from("foo");
    s.push_str("bar");
    println!("连接后的字符串: {}", s);
    
    // 使用 push 添加单个字符
    let mut s = String::from("lo");
    s.push('l');
    println!("添加字符后的字符串: {}", s);
    
    // 使用 + 连接字符串
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2;  // 注意 s1 被移动了，不能继续使用
    println!("连接的字符串: {}", s3);
    
    // 使用 format! 宏连接字符串
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");
    
    let s = format!("{}-{}-{}", s1, s2, s3);
    println!("格式化字符串: {}", s);
    
    // 4. 字符串索引
    let s = String::from("hello");
    // let h = s[0];  // 这会导致编译错误
    
    // 字节、标量值和字形簇
    for b in "नमस्ते".bytes() {
        println!("字节: {}", b);
    }
    
    for c in "नमस्ते".chars() {
        println!("字符: {}", c);
    }
    
    // 5. HashMap（哈希映射）
    use std::collections::HashMap;
    
    // 创建新的 HashMap
    let mut scores = HashMap::new();
    
    // 插入键值对
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
    
    // 访问 HashMap 中的值
    let team_name = String::from("Blue");
    let score = scores.get(&team_name);
    
    match score {
        Some(s) => println!("{} 队的分数: {}", team_name, s),
        None => println!("没有找到 {} 队的分数", team_name),
    }
    
    // 遍历 HashMap
    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
    
    // 6. 更新 HashMap
    // 覆盖一个值
    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Blue"), 25);
    println!("Blue 队的分数: {:?}", scores);
    
    // 只在键不存在时插入
    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    
    scores.entry(String::from("Yellow")).or_insert(50);
    scores.entry(String::from("Blue")).or_insert(50);
    
    println!("更新后的分数: {:?}", scores);
    
    // 基于旧值更新值
    let text = "hello world wonderful world";
    let mut map = HashMap::new();
    
    for word in text.split_whitespace() {
        let count = map.entry(word).or_insert(0);
        *count += 1;
    }
    
    println!("词频统计: {:?}", map);
}